<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useMainStore } from '@/store/index'
import { addDefect,defectImg,updateDefect } from '@/api/road/index'
import * as mars3d from "mars3d"
import type { UploadProps, UploadUserFile } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { getToken } from '@utils/auth'
import { ElMessage, ElMessageBox } from 'element-plus'
import { isPointInBetweenStations, getDefectDetail, deleteDefect } from '@/api/road/index'
import { ElLoading } from 'element-plus'
import { FormInstance } from 'element-plus'

const Cesium = mars3d.Cesium
const url = import.meta.env.VITE_APP_BASE_API + '/business/defectImg/upload'
interface info {
  name: string;
  category: string;
  colorChecked: string;
  elementId: string;
  folderId: string;
  childrenSort: number;
  type: string;
  geom: string;
  remark: string;
  color: string;
  distance: string;
}

// 扩展UploadUserFile类型以包含自定义属性
interface CustomUploadFile extends UploadUserFile {
  defectImgId?: string;
  type?: string;
  url?: string;
  name: string;
  status?: 'ready' | 'uploading' | 'success' | 'fail';
  percentage?: number;
  raw?: File;
  size?: number;
  response?: any;
}

const type = ref(-1) // 0是编辑 1是新增
const clientid = import.meta.env.VITE_APP_CLIENT_ID
const store = useMainStore()
const queryParams = ref({
  roadName: '',
  stakeNumber: '',
  direction:'',
  defectTime:'',
  defectType:'',
  defectLevel:'',
  computeFormula: '',
  defectArea:'',
  repairStatus:'待维修',
  rdefectImgIds:[],
  imgBeforeList: [],
  imgDuringList: [],
  imgAfterList: [],
  geom:''
})

const xx = ['上行','下行']
// const defectTypeList = ['路基','沥青路面','水泥路面','沿路设施','保洁','桥涵','隧道','边坡','绿化']
const defectTypeList = [
  {
    value: '路基',
    label: '路基',
    children: [
      {
        value: '路肩损坏',
        label: '路肩损坏',
      },
      {
        value: '边坡塌陷',
        label: '边坡塌陷',
      },
      {
        value: '水毁冲沟',
        label: '水毁冲沟',
      },
      {
        value: '路基构造物损坏',
        label: '路基构造物损坏',
      },
      {
        value: '路缘石缺损',
        label: '路缘石缺损',
      },
      {
        value: '路基沉降',
        label: '路基沉降',
      },
      {
        value: '排水不畅',
        label: '排水不畅',
      },
    ],
  },
  {
    value: '沥青路面',
    label: '沥青路面',
    children: [
      {
        value: '龟裂',
        label: '龟裂',
      },
      {
        value: '块状裂纹',
        label: '块状裂纹',
      },
      {
        value: '纵向裂纹',
        label: '纵向裂纹',
      },
      {
        value: '横向裂纹',
        label: '横向裂纹',
      },
      {
        value: '坑槽',
        label: '坑槽',
      },
      {
        value: '松散',
        label: '松散',
      },
      {
        value: '车辙',
        label: '车辙',
      },
      {
        value: '波浪拥包',
        label: '波浪拥包',
      },
      {
        value: '泛油',
        label: '泛油',
      },
      {
        value: '修补',
        label: '修补',
      },
    ],
  },
    {
    value: '水泥路面',
    label: '水泥路面',
    children: [
      {
        value: '破碎板',
        label: '破碎板',
      },
      {
        value: '裂缝',
        label: '裂缝',
      },
      {
        value: '板角断裂',
        label: '板角断裂',
      },
      {
        value: '错台',
        label: '错台',
      },
      {
        value: '拱起',
        label: '拱起',
      },
      {
        value: '边角剥落',
        label: '边角剥落',
      },
      {
        value: '接缝料损坏',
        label: '接缝料损坏',
      },
      {
        value: '坑洞',
        label: '坑洞',
      },
      {
        value: '唧泥',
        label: '唧泥',
      },
      {
        value: '露骨',
        label: '露骨',
      },
      {
        value: '修补',
        label: '修补',
      }
    ],
  },
    {
    value: '沿线设施',
    label: '沿线设施',
    children: [
      {
        value: '标志遮挡',
        label: '标志遮挡',
      },
      {
        value: '标志缺损',
        label: '标志缺损',
      },
      {
        value: '标线缺损',
        label: '标线缺损',
      },
      {
        value: '防护设施缺损',
        label: '防护设施缺损',
      },
      {
        value: '绿化管护不善',
        label: '绿化管护不善',
      },
      {
        value: '防眩板损坏',
        label: '防眩板损坏',
      },
      {
        value: '防抛网损坏',
        label: '防抛网损坏',
      }
    ],
  },
  {
    value: '保洁',
    label: '保洁',
    children: [
      {
        value: '抛洒物',
        label: '抛洒物',
      },
    ],
  },
  {
    value: '桥涵',
    label: '桥涵',
    children: [
      {
        value: '桥头跳车',
        label: '桥头跳车',
      },
      {
        value: '泄水孔堵塞',
        label: '泄水孔堵塞',
      },
      {
        value: '伸缩缝损坏',
        label: '伸缩缝损坏',
      },
      {
        value: '涵洞积水',
        label: '涵洞积水',
      },
    ],
  },
  {
    value: '隧道',
    label: '隧道',
    children: [
      {
        value: '隧道积水',
        label: '隧道积水',
      },
    ],
  },
  {
    value: '边坡',
    label: '边坡',
  },
  {
    value: '绿化',
    label: '绿化',
    children: [
      {
        value: '死株',
        label: '死株',
      },
      {
        value: '缺株',
        label: '缺株',
      },
      {
        value: '杂草',
        label: '杂草',
      },
    ],
  },
]
const defectLevelList = ['一般','轻','中','重']
const repairStatusList = [{
  label:'无需维修',
  value:'0',
  color:'#409EFF'
},{
  label:'待维修',
  value:'1',
  color:'#d9001b'
},{
  label:'已派单',
  value:'2',
  color:'#E6A23C'
},{
  label:'维修完成',
  value:'3',
  color:'#529b2e'
}]
const imgBeforeList = ref<CustomUploadFile[]>([])
const imgDuringList = ref<CustomUploadFile[]>([])
const imgAfterList = ref<CustomUploadFile[]>([])

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const queryFormRef = ref<FormInstance>()

const rules = ref({
  roadName: [{ required: true, message: '请输入道路名称', trigger: 'blur' }],
  stakeNumber: [{ required: true, message: '请输入桩号', trigger: 'blur' }],
  direction: [{ required: true, message: '请选择行向', trigger: 'change' }],
  defectTime: [{ required: true, message: '请选择时间', trigger: 'change' }],
  defectType: [{ required: true, message: '请选择缺陷类型', trigger: 'change' }],
  defectLevel: [{ required: true, message: '请选择缺陷等级', trigger: 'change' }],
  defectArea: [
    { required: true, message: '请输入缺陷面积', trigger: 'blur' },
    { type: 'number', message: '缺陷面积必须为数字值', transform: (value) => Number(value), trigger: ['blur', 'change'] }
  ],
  repairStatus: [{ required: true, message: '请选择维修状态', trigger: 'change' }],
  rdefectImgIds: [
    { 
      type: 'array', 
      required: true, 
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('请至少上传一张照片'));
        } else {
          callback();
        }
      },
      trigger: 'change' 
    }
  ],
  geom: [{ required: true, message: '图形几何信息不能为空', trigger: 'manual' }] // 'manual' trigger as it is auto-filled
})

// 重置表单
const resetQuery = () => {
  queryParams.value = {
    roadName: '',
    stakeNumber: '',
    direction:'',
    defectTime:'',
    defectType:'',
    defectLevel:'',
    computeFormula: '',
    defectArea:'',
    repairStatus:'待维修',
    rdefectImgIds:[],
    imgBeforeList: [],
    imgDuringList: [],
    imgAfterList: [],
    geom:''
  }

  type.value = -1
  imgBeforeList.value = []
  imgDuringList.value = []
  imgAfterList.value = []
}

// Helper function to delete inconsistent images
const deleteImageFiles = async (imagesToDelete: CustomUploadFile[], listNameToUpdate: 'imgBeforeList' | 'imgDuringList' | 'imgAfterList') => {
  if (!imagesToDelete || imagesToDelete.length === 0) return;

  let listNameForMessage = '';
  if (listNameToUpdate === 'imgBeforeList') listNameForMessage = '维修前照片';
  else if (listNameToUpdate === 'imgDuringList') listNameForMessage = '维修中照片';
  else if (listNameToUpdate === 'imgAfterList') listNameForMessage = '维修后照片';

  const loadingInstance = ElLoading.service({
    lock: true,
    text: `正在删除${listNameForMessage}中与当前状态不符的图片...`,
    background: 'rgba(0, 0, 0, 0.7)',
  });

  try {
    const successfullyDeletedIds: string[] = [];
    for (const imageFile of imagesToDelete) {
      if (imageFile.defectImgId) {
        try {
          const res = await defectImg(imageFile.defectImgId); // API call
          if (res.code === 200) {
            successfullyDeletedIds.push(imageFile.defectImgId);
            ElMessage.success(`图片 ${imageFile.name || imageFile.defectImgId} 已删除`);
          } else {
            ElMessage.error(`删除图片 ${imageFile.name || imageFile.defectImgId} 失败: ${res.msg}`);
          }
        } catch (apiError) {
          ElMessage.error(`删除图片 ${imageFile.name || imageFile.defectImgId} API调用失败`);
          console.error(`API error deleting image ${imageFile.defectImgId}:`, apiError);
        }
      }
    }

    if (successfullyDeletedIds.length > 0) {
      if (listNameToUpdate === 'imgBeforeList') {
        imgBeforeList.value = imgBeforeList.value.filter(f => !successfullyDeletedIds.includes(f.defectImgId!));
      } else if (listNameToUpdate === 'imgDuringList') {
        imgDuringList.value = imgDuringList.value.filter(f => !successfullyDeletedIds.includes(f.defectImgId!));
      } else if (listNameToUpdate === 'imgAfterList') {
        imgAfterList.value = imgAfterList.value.filter(f => !successfullyDeletedIds.includes(f.defectImgId!));
      }
      queryParams.value.rdefectImgIds = queryParams.value.rdefectImgIds.filter(id => !successfullyDeletedIds.includes(id));
      
      // Update queryParams image lists for consistency
      queryParams.value.imgBeforeList = [...imgBeforeList.value];
      queryParams.value.imgDuringList = [...imgDuringList.value];
      queryParams.value.imgAfterList = [...imgAfterList.value];
    }
  } finally {
    loadingInstance.close();
  }
};

const endEdit = async () => {
  const graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
  if(type.value == -1){
    return
  }
  else if(type.value == 0) {
    const loadingInstance = ElLoading.service({
      lock: true,
      text: '正在分析图形和数据，请稍后',
      background: 'rgba(0, 0, 0, 0.7)',
    })
    if(!store.graphicDefectSaved) {
      const isOnRoad = await grapgic2Wkt()
      if (!isOnRoad) {
        ElMessage.error('图形已偏离道路，请重新编辑！')
        window.graphicDefect.startEditing(graphic)
        loadingInstance.close()
        return
      }
    }

    let potentialRepairStatus = '';
    let suggestionMessage = '';

    if (imgAfterList.value.length > 0 && queryParams.value.repairStatus !== '维修完成') {
      potentialRepairStatus = '维修完成';
      suggestionMessage = '检测到已上传维修后照片，是否将维修状态更新为"维修完成"？';
    } else if (imgDuringList.value.length > 0 && 
               queryParams.value.repairStatus !== '已派单' && 
               queryParams.value.repairStatus !== '维修完成') {
      potentialRepairStatus = '已派单';
      suggestionMessage = '检测到已上传维修中照片，是否将维修状态更新为"已派单"？';
    } else if (imgBeforeList.value.length > 0 && queryParams.value.repairStatus === '无需维修') {
      potentialRepairStatus = '待维修';
      suggestionMessage = '检测到已上传维修前照片，但当前状态为"无需维修"，是否将维修状态更新为"待维修"？';
    }

    if (suggestionMessage) {
      try {
        await ElMessageBox.confirm(suggestionMessage, '维修状态提示', {
          confirmButtonText: '更新状态',
          cancelButtonText: '保持原状',
          type: 'info'
        });
        queryParams.value.repairStatus = potentialRepairStatus;
        changeColor();
        ElMessage.success(`维修状态已更新为"${potentialRepairStatus}"`);
      } catch (action) {
        ElMessage.info('维修状态未作修改。');
        
        const currentRepairStatus = queryParams.value.repairStatus;
        
        if (currentRepairStatus === '待维修') {
          await deleteImageFiles([...imgDuringList.value], 'imgDuringList');
          await deleteImageFiles([...imgAfterList.value], 'imgAfterList');
        } else if (currentRepairStatus === '无需维修') {
          await deleteImageFiles([...imgBeforeList.value], 'imgBeforeList');
          await deleteImageFiles([...imgDuringList.value], 'imgDuringList');
          await deleteImageFiles([...imgAfterList.value], 'imgAfterList');
        } else if (currentRepairStatus === '已派单') {
          await deleteImageFiles([...imgAfterList.value], 'imgAfterList');
        }
      }
    }
    
    graphic.options.attr.rdefectImgIds = []
    try {graphic.options.attr.imgBeforeList.forEach(item=>{graphic.options.attr.rdefectImgIds.push(item.defectImgId)})} catch (error) {console.log(error);} 
    try {graphic.options.attr.imgDuringList.forEach(item=>{graphic.options.attr.rdefectImgIds.push(item.defectImgId)})} catch (error) {console.log(error);} 
    try {graphic.options.attr.imgAfterList.forEach(item=>{graphic.options.attr.rdefectImgIds.push(item.defectImgId)})} catch (error) {console.log(error);}
    const hasChanges = checkForChanges(graphic.options.attr, queryParams.value)
    loadingInstance.close() 

    if (hasChanges) {
      queryParams.value.defectType = typeof(queryParams.value.defectType) === 'string' ?queryParams.value.defectType : queryParams.value.defectType[1]
      ElMessageBox.confirm('您还未保存该缺陷, 是否保存?', '提示', {
        confirmButtonText: '保存',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        saveEdit()
      }).catch(() => {
        unsave()
      })
    } else {
      store.graphicDefectId = ''
      store.isOpenTabel = true
      store.graphicDefectOperate = '结束编辑'
      ElMessage({showClose: true, message: '内容无修改'})
      resetQuery()
      window.graphicDefect.endDraw()
    }
  } else {
      queryParams.value.defectType = typeof(queryParams.value.defectType) === 'string' ?queryParams.value.defectType : queryParams.value.defectType[1]
    if(store.graphicDefectId != '') {
      ElMessageBox.confirm('您还未保存该缺陷, 是否保存?', '提示', {
        confirmButtonText: '保存',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        submit()
      }).catch(() => {
        unsave()
      })
    }
  }
}

// 检查数据是否有变更
const checkForChanges = (original: any, current: any) => {
  if (!original || !store.graphicDefectSaved) return true // 如果是新增或未保存的图形，则视为有变更

  // 检查基本信息
  const basicFields = ['roadName', 'stakeNumber', 'direction', 'defectTime', 
    'defectType', 'defectLevel', 'defectArea', 'repairStatus']
  
  for (const field of basicFields) {
    if (original[field] != current[field]) {
      console.log('Basic field changed:', field, original[field], current[field]);
      return true
    }
  }

  // 检查图片列表
  const checkImageListsChanged = (originalIds?: string[], currentIds?: string[]) => {
    const oIds = originalIds || [];
    const cIds = currentIds || [];

    if (oIds.length !== cIds.length) {
      console.log('Image lists length changed:', oIds.length, cIds.length);
      return true; // Different lengths mean change
    }

    const originalSet = new Set(oIds);
    for (const id of cIds) {
      if (!originalSet.has(id)) {
        console.log('Image ID in current not in original:', id);
        return true; // ID in current not in original
      }
    }
    // Since lengths are the same and all current IDs are in original, the sets are identical.
    return false; // No change
  };

  const imagesHaveChanged = checkImageListsChanged(original.rdefectImgIds, current.rdefectImgIds);
  if (imagesHaveChanged) {
    console.log('Image lists have changed.');
  }

  return imagesHaveChanged;
}

// 删除缺陷
const delEdit = async () => {
  ElMessageBox.confirm('是否确定删除该缺陷?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const loadingInstance = ElLoading.service({
      lock: true,
      text: '正在删除，请稍后',
      background: 'rgba(0, 0, 0, 0.7)',
    })
    await deleteDefect(store.graphicDefectId).then(res=>{
      if(res.code === 200) {
        ElMessage.success('删除成功')
        window.graphicDefect.removeGraphic(window.graphicDefect.getGraphicById(store.graphicDefectId))
        loadingInstance.close()
        resetQuery()
        store.graphicDefectId = ''
        store.isOpenTabel = true
        store.graphicDefectOperate = '结束编辑'
        window.getListInfo()
      }
    })
  }).catch(() => {
    ElMessage({showClose: true, message: '已取消删除'})
  })
}

// 新增缺陷
const submit = () => {
  addDefect(JSON.stringify(queryParams.value)).then(async res=>{
    if(res.code === 200) {
      ElMessage.success('提交成功')
      let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
      graphic.options.attr.geomId = res.data
      store.graphicDefectId = res.data
      await resetGraphic(res.data)
      resetQuery()
      store.graphicDefectId = ''
      store.isOpenTabel = true
      store.graphicDefectOperate = '结束编辑'
      window.graphicDefect.removeGraphic(graphic)
      window.getListInfo()
    }
  })
}

// 修改缺陷
const saveEdit = () => {
  updateDefect(JSON.stringify(queryParams.value)).then(res=>{
    if(res.code === 200) {
      ElMessage.success('保存成功')
      let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
      graphic.options.attr = {
        ...queryParams.value,
        imgBeforeList: imgBeforeList.value,
        imgDuringList: imgDuringList.value,
        imgAfterList: imgAfterList.value
      }
      graphic.setStyle({label: {text: queryParams.value.defectType}})
      window.graphicDefect.stopEditing()
      resetQuery()
      store.graphicDefectId = ''
      store.isOpenTabel = true
      store.graphicDefectOperate = '结束编辑'
      window.getListInfo()
    }
  })  
}

// 不保存缺陷
const unsave = async () => {
  window.graphicDefect.removeGraphic(window.graphicDefect.getGraphicById(store.graphicDefectId))
  if(type.value == 0) {
    await resetGraphic(store.graphicDefectId)
  }
  ElMessage({showClose: true,message: '取消修改'});
  store.graphicDefectId = ''
  store.isOpenTabel = true
  store.graphicDefectOperate = '结束编辑'
  resetQuery()
}

const resetGraphic = async (graphicDefectId) => {
  await getDefectDetail(graphicDefectId).then(res=>{
    if(res.code === 200) {
      let item = res.data
      const result = parseMultipolygon(item.geom).slice(0, -1);
      window.graphicDefect.addGraphic({
        id:item.defectId,
        name:item.roadName,
        positions:result,
        type: "polygon",
        attr:{...item},
        style: {
            color: item.repairStatus=="无需维修"?'#409EFF':item.repairStatus=="待维修"?'#d9001b':item.repairStatus=="已派单"?'#E6A23C':'#529b2e',
            outline: true,
            opacity: 0.3,
            outlineColor: item.repairStatus=="无需维修"?'#409EFF':item.repairStatus=="待维修"?'#d9001b':item.repairStatus=="已派单"?'#E6A23C':'#529b2e',
            outlineWidth: 2.0,
            edittype:"polygon",
            label: {
              text: item.defectType,
              color: '#fff',
              outline:true,
              outlineColor: "#000",
              outlineWidth:4,
              setHeight:5,
              scaleByDistance:true,
            }
        }
      })
    }
  })

}

const handleRemove: UploadProps['onRemove'] = (uploadFile: CustomUploadFile, uploadFiles) => {
  // 检查uploadFile是否包含uid属性
  let defectImgId = uploadFile.defectImgId
  if (!defectImgId) return
  
  defectImg(defectImgId).then(res=>{
    if(res.code === 200) {
      ElMessage.success('删除成功')
      // 根据类型和图片类型更新对应的列表
      imgBeforeList.value = imgBeforeList.value.filter(file => file.defectImgId !== defectImgId)
      imgDuringList.value = imgDuringList.value.filter(file => file.defectImgId !== defectImgId)
      imgAfterList.value = imgAfterList.value.filter(file => file.defectImgId !== defectImgId)
      // 从ID列表中移除
      queryParams.value.rdefectImgIds = queryParams.value.rdefectImgIds.filter(id => id !== defectImgId)
      // 更新queryParams中的图片列表
      queryParams.value.imgBeforeList = imgBeforeList.value
      queryParams.value.imgDuringList = imgDuringList.value
      queryParams.value.imgAfterList = imgAfterList.value
    }
  })
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

const changeColor = () => {
  let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
  if(queryParams.value.repairStatus == '无需维修') {
    graphic.setOptions({
      style: {
          color:'#409EFF',
          outlineColor:'#409EFF',
      }
    })
  }else if(queryParams.value.repairStatus == '待维修') {
    graphic.setOptions({
      style: {
          color:'#d9001b',
          outlineColor:'#d9001b',
      }
    })
  }else if(queryParams.value.repairStatus == '已派单') {
    graphic.setOptions({
      style: {
          color:'#E6A23C',
          outlineColor:'#E6A23C',
      }
    })
  }else if(queryParams.value.repairStatus == '维修完成') {
    graphic.setOptions({
      style: {
          color:'#529b2e',
          outlineColor:'#529b2e',
      }
    })
  }
}

const beforeSuccess = (response: any, file: CustomUploadFile, uploadFiles: CustomUploadFile[]) => {
  if(response.code === 200) {
    if (!queryParams.value.rdefectImgIds) {
      queryParams.value.rdefectImgIds = []
    }
    if (!queryParams.value.imgBeforeList) {
      queryParams.value.imgBeforeList = []
    }
    const defectImgId = response.data
    file.defectImgId = defectImgId
    queryParams.value.rdefectImgIds.push(defectImgId)
    ElMessage.success('上传成功')
  }
}

const duringSuccess = (response: any, file: CustomUploadFile, uploadFiles: CustomUploadFile[]) => {
  if(response.code === 200) {
    if (!queryParams.value.rdefectImgIds) {
      queryParams.value.rdefectImgIds = []
    }
    if (!queryParams.value.imgDuringList) {
      queryParams.value.imgDuringList = []
    }
    const defectImgId = response.data
    file.defectImgId = defectImgId
    queryParams.value.rdefectImgIds.push(defectImgId)
    ElMessage.success('上传成功')
  }
}

const afterSuccess = (response: any, file: CustomUploadFile, uploadFiles: CustomUploadFile[]) => {
  if(response.code === 200) {
    if (!queryParams.value.rdefectImgIds) {
      queryParams.value.rdefectImgIds = []
    }
    if (!queryParams.value.imgAfterList) {
      queryParams.value.imgAfterList = []
    }
    const defectImgId = response.data
    file.defectImgId = defectImgId
    queryParams.value.rdefectImgIds.push(defectImgId)
    ElMessage.success('上传成功')
  }
}

const parseMultipolygon = (multipolygonStr) => {
  // 1. 提取最内层的坐标字符串
  const coordinatesMatch = multipolygonStr.match(/\(\(\(([^)]+)\)\)\)/);
  if (!coordinatesMatch) return [];
  
  // 2. 分割坐标点并处理
  const points = coordinatesMatch[1].split(',')
    .map(pointStr => {
      // 移除可能存在的空格并分割经纬度
      const [lng, lat] = pointStr.trim().split(/\s+/);
      
      // 转换为浮点数并返回数组
      return [parseFloat(lng), parseFloat(lat)];
    });

  return points;
}

const grapgic2Wkt = async () => {
  try {
    let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
    const degreesPositions = graphic.outlinePositions.map(cartesian => {
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
      return [
        Cesium.Math.toDegrees(cartographic.longitude),
        Cesium.Math.toDegrees(cartographic.latitude),
        cartographic.height
      ]
    })
    const coordinates = degreesPositions.map(pos => `${pos[0]} ${pos[1]}`).join(',')
    const wkt = `MULTIPOLYGON(((${coordinates})))`
    
    const res = await isPointInBetweenStations({'geometry': wkt})
    if (res.code === 200) {
      if (res.data != null) {
        queryParams.value.geom = wkt
        queryParams.value.stakeNumber = res.data.pileNum
        return true
      }
    }
    return false
  } catch (error) {
    console.error('Error in grapgic2Wkt:', error)
    return false
  }
}

onMounted(()=>{
})


const startEdit = () => {
  // Reset form validation state first
  if (queryFormRef.value) {
    queryFormRef.value.clearValidate();
  }

  let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
  resetQuery() // This resets queryParams and image lists
  
  if(graphic.options.attr.defectId) { // Editing existing defect
    type.value = 0
    // Ensure all necessary arrays are initialized before assignment
    const attr = {
      ...graphic.options.attr,
      rdefectImgIds: [], // Start with an empty array, will be populated below
      imgBeforeList: graphic.options.attr.imgBeforeList || [],
      imgDuringList: graphic.options.attr.imgDuringList || [],
      imgAfterList: graphic.options.attr.imgAfterList || []
    }
    queryParams.value = { ...attr }; // Assign all attributes

    // Initialize component's reactive image lists and populate rdefectImgIds from queryParams
    imgBeforeList.value = []
    imgDuringList.value = []
    imgAfterList.value = []

    if (queryParams.value.imgBeforeList) {
      queryParams.value.imgBeforeList.forEach(item => {
        if (item.defectImgId) {
          imgBeforeList.value.push(item as CustomUploadFile); // Cast to ensure type compatibility
          queryParams.value.rdefectImgIds.push(item.defectImgId);
        }
      });
    }
    if (queryParams.value.imgDuringList) {
      queryParams.value.imgDuringList.forEach(item => {
        if (item.defectImgId) {
          imgDuringList.value.push(item as CustomUploadFile);
          queryParams.value.rdefectImgIds.push(item.defectImgId);
        }
      });
    }
    if (queryParams.value.imgAfterList) {
      queryParams.value.imgAfterList.forEach(item => {
        if (item.defectImgId) {
          imgAfterList.value.push(item as CustomUploadFile);
          queryParams.value.rdefectImgIds.push(item.defectImgId);
        }
      });
    }
    // Ensure rdefectImgIds is unique if items were duplicated from graphic.options.attr and then re-added
    queryParams.value.rdefectImgIds = [...new Set(queryParams.value.rdefectImgIds)];

  } else { // Adding new defect
    type.value = 1
    // Populate some fields for a new defect
    queryParams.value.roadName = graphic.options.attr.roadName || '' // Ensure roadName is initialized
    queryParams.value.stakeNumber = graphic.options.attr.stakeNumber || '' // Ensure stakeNumber is initialized
    queryParams.value.computeFormula = graphic.options.attr.computeFormula || '' // Ensure stakeNumber is initialized
    queryParams.value.defectTime = new Date().toISOString().substring(0, 10)
    queryParams.value.defectArea = mars3d.MeasureUtil.getArea(graphic.getCoordinates()).toFixed(2)

    const degreesPositions = graphic.outlinePositions.map(cartesian => {
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      return [
        Cesium.Math.toDegrees(cartographic.longitude),
        Cesium.Math.toDegrees(cartographic.latitude),
        cartographic.height
      ];
    });
    queryParams.value.geom = `MULTIPOLYGON(((${degreesPositions.map(pos => `${pos[0]} ${pos[1]}`).join(',')})))`;

    splitGraphicToRectangles()
  }
}

const resetdefectArea = async () => {
  let graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
  queryParams.value.defectArea = mars3d.MeasureUtil.getArea(graphic.getCoordinates()).toFixed(2)
}

// 将startEdit函数挂载到全局
window.startEdit = startEdit
window.endEdit = endEdit
window.resetdefectArea = resetdefectArea

// 切分图形为最大矩形
const splitGraphicToRectangles = () => {
  if (!store.graphicDefectId) {
    ElMessage.warning('请先选择一个图形')
    return
  }
  
  const graphic = window.graphicDefect.getGraphicById(store.graphicDefectId)
  if (!graphic) {
    ElMessage.warning('未找到选中的图形')
    return
  }
  
  try {
    console.log("正在分析多边形图形...")
    
    // 获取多边形的坐标点
    const positions = graphic.outlinePositions.slice(0, -1) // 去除最后一个点，因为它是重复的
    if (!positions || positions.length < 3) {
      console.warn("图形点数不足，无法切分")
      return
    }
    
    // 获取原始多边形的面积
    const originalArea = mars3d.MeasureUtil.getArea(graphic.getCoordinates())
    console.log(`原始多边形面积: ${originalArea.toFixed(2)} 平方米`)
    
    // 计算并显示各边长度
    console.log("各边长度计算:")
    let totalLength = 0
    const edgeLengths = []
    const edges = [] // 存储边的向量信息
    
    for (let i = 0; i < positions.length; i++) {
      const p1 = positions[i]
      const p2 = positions[(i + 1) % positions.length]
      
      // 使用Cesium计算两点间的距离
      const distance = Cesium.Cartesian3.distance(p1, p2)
      
      // 计算边的向量
      const edge = {
        start: p1,
        end: p2,
        length: distance,
        vector: new Cesium.Cartesian3()
      }
      
      // 计算边的方向向量
      Cesium.Cartesian3.subtract(p2, p1, edge.vector)
      Cesium.Cartesian3.normalize(edge.vector, edge.vector)
      
      edges.push(edge)
      edgeLengths.push(distance)
      totalLength += distance
      
      console.log(`边 ${i+1}: ${distance.toFixed(2)} 米`)
    }
    
    // 1. 将第一个点作为坐标原点建立直角坐标系
    console.log("建立以第一个点为原点的直角坐标系...")
    
    // 获取第一个点的笛卡尔坐标
    const origin = positions[0]
    
    // 将笛卡尔坐标转换为经纬度坐标
    const cartographic = Cesium.Cartographic.fromCartesian(origin)
    const originLon = Cesium.Math.toDegrees(cartographic.longitude)
    const originLat = Cesium.Math.toDegrees(cartographic.latitude)
    const originHeight = cartographic.height
    
    console.log(`原点经纬度: ${originLon.toFixed(6)}, ${originLat.toFixed(6)}, 高度: ${originHeight.toFixed(2)}米`)
    
    // 2. 建立直角坐标系，计算每个点在直角坐标系中的位置
    const localCoordinates = []
    
    // 定义坐标系的两个基向量（以第一条边和第二条边为基础）
    const xAxis = edges[0].vector
    const yAxisTemp = edges[1].vector
    
    // 确保y轴与x轴垂直（叉积后再叉积）
    const zAxis = new Cesium.Cartesian3()
    Cesium.Cartesian3.cross(xAxis, yAxisTemp, zAxis)
    Cesium.Cartesian3.normalize(zAxis, zAxis)
    
    const yAxis = new Cesium.Cartesian3()
    Cesium.Cartesian3.cross(zAxis, xAxis, yAxis)
    Cesium.Cartesian3.normalize(yAxis, yAxis)
    
    // 第一个点是原点 (0,0)
    localCoordinates.push({ x: 0, y: 0 })
    
    // 计算其他点在这个坐标系中的位置
    for (let i = 1; i < positions.length; i++) {
      // 计算从原点到当前点的向量
      const toPoint = new Cesium.Cartesian3()
      Cesium.Cartesian3.subtract(positions[i], origin, toPoint)
      
      // 计算在x轴和y轴上的投影
      const xProj = Cesium.Cartesian3.dot(toPoint, xAxis)
      const yProj = Cesium.Cartesian3.dot(toPoint, yAxis)
      
      localCoordinates.push({ x: xProj, y: yProj })
    }
    
    console.log(positions)
    
    // 计算凹顶点数量
    const concaveVertices = findConcaveVertices(localCoordinates)
    console.log(`凹顶点数量: ${concaveVertices.length}`)
    
    // 预期的矩形数量为凹顶点数量加1
    const expectedRectangles = concaveVertices.length + 1
    console.log(`预期矩形数量: ${expectedRectangles}`)
    
    // 递归分解多边形为矩形
    const rectangles = decomposePolygon(localCoordinates)
    console.log(`分解得到的矩形数量: ${rectangles.length}`)
    console.log("分解得到的矩形:", rectangles)
    
    // 计算所有矩形的总面积
    let totalArea = 0
    let formulaParts = []
    
    rectangles.forEach((rect, index) => {
      const area = rect.width * rect.height
      totalArea += area
      formulaParts.push(`${rect.width.toFixed(2)}×${rect.height.toFixed(2)}`)
      console.log(`矩形${index+1}面积: ${area.toFixed(2)} 平方米 (${rect.width.toFixed(2)}×${rect.height.toFixed(2)})`)
    })
    
    // 更新计算公式
    if (rectangles.length === 1) {
      // 只有一个矩形时直接使用其面积公式
      const rect = rectangles[0]
      queryParams.value.computeFormula = `${rect.width.toFixed(2)} × ${rect.height.toFixed(2)}`
    } else {
      // 多个矩形时合并所有矩形的面积公式
      queryParams.value.computeFormula = formulaParts.join(' + ')
    }
    
    console.log(`总面积: ${totalArea.toFixed(2)} 平方米`)
    console.log(`计算公式: ${queryParams.value.computeFormula}`)
    
    // 输出直角坐标系中的坐标
    console.log("直角坐标系中的点位置:")
    localCoordinates.forEach((coord, index) => {
      console.log(`点 ${index + 1}: (${coord.x.toFixed(2)}, ${coord.y.toFixed(2)})`)
    })
    
    // 显示消息
    ElMessage.success(`成功分解为${rectangles.length}个矩形，总面积${totalArea.toFixed(2)}平方米`)
    
  } catch (error) {
    console.error('计算面积失败:', error)
    ElMessage.error('计算面积失败，请查看控制台获取详细信息')
  }
}

// 判断点是否在多边形内部
const pointInPolygon = (point, polygon) => {
  // 使用射线法判断点是否在多边形内部
  let inside = false
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i].x
    const yi = polygon[i].y
    const xj = polygon[j].x
    const yj = polygon[j].y
    
    const intersect = ((yi > point.y) !== (yj > point.y)) &&
      (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi)
    
    if (intersect) inside = !inside
  }
  
  return inside
}

// 检查矩形是否在多边形内部
const rectangleInPolygon = (rect, polygon) => {
  // 检查矩形的四个角点是否都在多边形内部
  const corners = [
    { x: rect.x, y: rect.y },                     // 左下
    { x: rect.x + rect.width, y: rect.y },        // 右下
    { x: rect.x + rect.width, y: rect.y + rect.height }, // 右上
    { x: rect.x, y: rect.y + rect.height }        // 左上
  ]
  
  return corners.every(corner => pointInPolygon(corner, polygon))
}

// 找到多边形中的最大矩形
const findLargestRectangle = (polygon) => {
  // 找到多边形的边界框
  const minX = Math.min(...polygon.map(p => p.x))
  const maxX = Math.max(...polygon.map(p => p.x))
  const minY = Math.min(...polygon.map(p => p.y))
  const maxY = Math.max(...polygon.map(p => p.y))
  
  // 离散化坐标
  const xCoords = [...new Set(polygon.map(p => p.x))].sort((a, b) => a - b)
  const yCoords = [...new Set(polygon.map(p => p.y))].sort((a, b) => a - b)
  
  let maxArea = 0
  let maxRect = null
  
  // 枚举所有可能的矩形（使用离散化的坐标）
  for (let i = 0; i < xCoords.length; i++) {
    for (let j = i + 1; j < xCoords.length; j++) {
      for (let k = 0; k < yCoords.length; k++) {
        for (let l = k + 1; l < yCoords.length; l++) {
          const rect = {
            x: xCoords[i],
            y: yCoords[k],
            width: xCoords[j] - xCoords[i],
            height: yCoords[l] - yCoords[k]
          }
          
          // 检查矩形是否在多边形内部
          if (rectangleInPolygon(rect, polygon)) {
            const area = rect.width * rect.height
            if (area > maxArea) {
              maxArea = area
              maxRect = rect
            }
          }
        }
      }
    }
  }
  
  return maxRect
}

// 计算向量叉积
const crossProduct = (p1, p2, p3) => {
  return (p2.x - p1.x) * (p3.y - p2.y) - (p2.y - p1.y) * (p3.x - p2.x)
}

// 找出多边形的凹顶点
const findConcaveVertices = (polygon) => {
  const n = polygon.length
  const concaveVertices = []
  
  for (let i = 0; i < n; i++) {
    const prev = polygon[(i - 1 + n) % n]
    const curr = polygon[i]
    const next = polygon[(i + 1) % n]
    
    // 计算叉积，如果为正，则为凹顶点（假设多边形顶点按顺时针排列）
    if (crossProduct(prev, curr, next) > 0) {
      concaveVertices.push(i)
    }
  }
  
  return concaveVertices
}

// 从多边形中减去矩形，返回剩余的多边形（可能是多个）
const subtractRectangle = (polygon, rect) => {
  // 创建矩形的四个顶点
  const rectVertices = [
    { x: rect.x, y: rect.y },                     // 左下
    { x: rect.x + rect.width, y: rect.y },        // 右下
    { x: rect.x + rect.width, y: rect.y + rect.height }, // 右上
    { x: rect.x, y: rect.y + rect.height }        // 左上
  ]
  
  // 使用裁剪算法从多边形中减去矩形
  // 这里使用简化方法：将多边形分割成最多4个子多边形
  const remainingPolygons = []
  
  // 左侧区域
  const leftPolygon = polygon.filter(p => p.x < rect.x)
  if (leftPolygon.length > 2) remainingPolygons.push(leftPolygon)
  
  // 右侧区域
  const rightPolygon = polygon.filter(p => p.x > rect.x + rect.width)
  if (rightPolygon.length > 2) remainingPolygons.push(rightPolygon)
  
  // 上侧区域
  const topPolygon = polygon.filter(p => p.y > rect.y + rect.height)
  if (topPolygon.length > 2) remainingPolygons.push(topPolygon)
  
  // 下侧区域
  const bottomPolygon = polygon.filter(p => p.y < rect.y)
  if (bottomPolygon.length > 2) remainingPolygons.push(bottomPolygon)
  
  return remainingPolygons
}

// 检查多边形是否为矩形
const isRectangle = (polygon) => {
  if (polygon.length !== 4) return false
  
  // 检查四个角是否都是90度
  for (let i = 0; i < 4; i++) {
    const prev = polygon[(i - 1 + 4) % 4]
    const curr = polygon[i]
    const next = polygon[(i + 1) % 4]
    
    // 计算两个边向量
    const v1 = { x: prev.x - curr.x, y: prev.y - curr.y }
    const v2 = { x: next.x - curr.x, y: next.y - curr.y }
    
    // 计算点积，如果不接近0，则不是直角
    const dotProduct = v1.x * v2.x + v1.y * v2.y
    if (Math.abs(dotProduct) > 0.01) return false
  }
  
  return true
}

// 递归分解多边形为矩形
const decomposePolygon = (polygon) => {
  // 如果多边形已经是矩形，直接返回
  if (isRectangle(polygon)) {
    // 计算矩形的宽度和高度
    const minX = Math.min(...polygon.map(p => p.x))
    const maxX = Math.max(...polygon.map(p => p.x))
    const minY = Math.min(...polygon.map(p => p.y))
    const maxY = Math.max(...polygon.map(p => p.y))
    
    return [{
      x: minX,
      y: minY,
      width: maxX - minX,
      height: maxY - minY
    }]
  }
  
  // 找到多边形中的最大矩形
  const maxRect = findLargestRectangle(polygon)
  // 如果找不到有效的矩形，返回空数组
  if (!maxRect) return []
  
  // 从多边形中减去最大矩形，得到剩余的多边形
  const remainingPolygons = subtractRectangle(polygon, maxRect)
  console.log('剩余的多边形',remainingPolygons)

  // 递归处理剩余的多边形
  let rectangles = [maxRect]
  for (const subPolygon of remainingPolygons) {
    rectangles = rectangles.concat(decomposePolygon(subPolygon))
  }
  
  return rectangles
}

</script>

<template>
<div :class="!store.isOpenTabel && store.graphicDefectOperate == '开始编辑' ?'qxInfoBox show':'qxInfoBox'">
  <div class="content-wrapper">
    <div class="title">
      <h3>道路缺陷</h3>
    </div>
    <div class="FormBox">
        <el-form ref="queryFormRef" :model="queryParams" :rules="rules" :inline="true">
          <el-form-item label="道路名称" prop="roadName">
            <el-input v-model="queryParams.roadName" placeholder="请输入道路名称" clearable />
          </el-form-item>
          <el-form-item label="桩号" prop="stakeNumber">
            <el-input v-model="queryParams.stakeNumber" placeholder="请输入桩号" clearable />
          </el-form-item>
          <el-form-item label="行向" prop="direction">
            <el-select v-model="queryParams.direction" filterable clearable placeholder="请选择行向">
              <el-option v-for="item in xx" :key="item" :label="item" :value="item"> </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="时间" prop="defectTime">
            <el-date-picker
              v-model="queryParams.defectTime"
              type="date"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              placeholder="选择日期"
              clearable
            >
            </el-date-picker>
          </el-form-item>
          <el-form-item label="缺陷类型" prop="defectType">
            <!-- <el-select v-model="queryParams.defectType" filterable clearable placeholder="请选择缺陷类型">
              <el-option v-for="item in defectTypeList" :key="item" :label="item" :value="item"> </el-option>
            </el-select> -->

            <el-cascader v-model="queryParams.defectType" :options="defectTypeList" label="value" :show-all-levels="false" />
          </el-form-item>
          <el-form-item label="缺陷等级" prop="defectLevel">
            <el-select v-model="queryParams.defectLevel" filterable clearable placeholder="请选择缺陷等级">
              <el-option v-for="item in defectLevelList" :key="item" :label="item" :value="item"> </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="计算式" prop="computeFormula">
            <el-input v-model="queryParams.computeFormula" placeholder="请输入计算式"/>
          </el-form-item>
          <el-form-item label="缺陷面积" prop="defectArea">
            <el-input type="number" v-model="queryParams.defectArea" placeholder="请输入缺面积"/>
          </el-form-item>
          <el-form-item label="维修状态" prop="repairStatus">
            <el-select v-model="queryParams.repairStatus" filterable clearable placeholder="请选择维修状态" @change="changeColor">
              <el-option v-for="item in repairStatusList" :key="item.value" :label="item.label" :value="item.label">
                <span>{{ item.label }}</span>
              </el-option>
            </el-select>
          </el-form-item>

          <!-- Form item for rdefectImgIds validation -->
          <el-form-item prop="rdefectImgIds" style="display: none;"></el-form-item>

          <el-form-item label="维修前照片">
            <div class="upload-container">
                <el-upload
                  v-model:file-list="imgBeforeList"
                  :action="url"
                  :data="{ type:'维修前' }"
                  :headers="{'Authorization': 'Bearer ' + getToken(),'clientid': clientid}"
                  list-type="picture-card"
                  :on-preview="handlePictureCardPreview"
                  :on-success="beforeSuccess"
                  :on-remove="handleRemove"
                >
                  <el-icon><Plus /></el-icon>
                </el-upload>
                <el-dialog v-model="dialogVisible" title="预览">
                  <img w-full :src="dialogImageUrl" alt="Preview Image" />
                </el-dialog>
            </div>
          </el-form-item>

          <el-form-item label="维修中照片">
            <div class="upload-container">
                <el-upload
                  v-model:file-list="imgDuringList"
                  :action="url"
                  :data="{ type:'维修中' }"
                  :headers="{'Authorization': 'Bearer ' + getToken(),'clientid': clientid}"
                  list-type="picture-card"
                  :on-preview="handlePictureCardPreview"
                  :on-success="duringSuccess"
                  :on-remove="handleRemove"
                >
                  <el-icon><Plus /></el-icon>
                </el-upload>
            </div>
          </el-form-item>

          <el-form-item label="维修后照片">
            <div class="upload-container">
                <el-upload
                  v-model:file-list="imgAfterList"
                  :action="url"
                  :data="{ type:'维修后' }"
                  :headers="{'Authorization': 'Bearer ' + getToken(),'clientid': clientid}"
                  list-type="picture-card"
                  :on-preview="handlePictureCardPreview"
                  :on-success="afterSuccess"
                  :on-remove="handleRemove"
                >
                  <el-icon><Plus /></el-icon>
                </el-upload>
            </div>
          </el-form-item>

          <!-- Form item for geom validation -->
          <el-form-item prop="geom" style="display: none;"></el-form-item>

          <!-- 添加切分按钮 -->
          <!-- <el-form-item>
            <el-button type="primary" @click="splitGraphicToRectangles">切分为最大矩形</el-button>
          </el-form-item> -->

        </el-form>

        <div>
          <div class="btnBox" v-if="type==1">
            <el-button @click="unsave">取消</el-button>
            <el-button type="primary" @click="endEdit">提交</el-button>
          </div>
          <div class="btnBox" v-else>
            <el-button type="danger" @click="delEdit">删除</el-button>
            <el-button type="success" @click="endEdit">保存</el-button>
            <!-- <el-button type="primary" @click="splitGraphicToRectangles">切分矩形</el-button> -->
          </div>
      </div>
    </div>
  </div>
</div>
</template>

<style scoped>
.qxInfoBox {
  box-sizing: border-box;
  position: fixed;
  left: -100%;
  top: 0;
  width: 370px;
  height: 100vh;
  background: rgba(19, 32, 57, 0.9);
  transition: all .8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  padding: 20px;
  z-index: 99;
  color: #fff;
  display: flex;
  flex-direction: column;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
  font-family: "思源黑体", "Roboto", sans-serif;
}

.qxInfoBox.show {
  left: 0;
}

.content-wrapper {
  height: 100%;
  display: flex;
  flex-direction: column;
  position: relative;
}

.title {
  text-align: center;
  margin-bottom: 20px;
  font-size: 20px;
  font-weight: bold;
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 10px 0;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.qxInfoBox ::v-deep label,
.qxInfoBox ::v-deep .el-form-item__label {
  color: white;
  width: 90px;
  display: inline-block;
  text-align: justify;
  text-align-last: justify;
}

/* 统一所有表单控件宽度和样式 */
.qxInfoBox ::v-deep .el-input,
.qxInfoBox ::v-deep .el-select,
.qxInfoBox ::v-deep .el-date-editor,
.qxInfoBox ::v-deep .el-cascader {
  width: 200px !important;
}

/* 统一输入框样式 */
.qxInfoBox ::v-deep .el-input__wrapper,
.qxInfoBox ::v-deep .el-select__wrapper,
.qxInfoBox ::v-deep .el-date-editor.el-input__wrapper,
.qxInfoBox ::v-deep .el-cascader__wrapper {
  background: rgba(26, 58, 111, 0.3);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.2) inset !important;
  border-radius: 4px;
  height: 32px;
}

/* 统一输入框聚焦样式 */
.qxInfoBox ::v-deep .el-input__wrapper.is-focus,
.qxInfoBox ::v-deep .el-select .el-input__wrapper.is-focus,
.qxInfoBox ::v-deep .el-cascader .el-input__wrapper.is-focus {
  box-shadow: 0 0 0 1px #005BAA inset !important;
}

/* 统一输入框文字颜色 */
.qxInfoBox ::v-deep .el-input__inner,
.qxInfoBox ::v-deep .el-select .el-input__inner,
.qxInfoBox ::v-deep .el-cascader .el-input__inner {
  color: #fff;
  height: 32px;
  line-height: 32px;
}

/* 确保表单项对齐 */
.qxInfoBox ::v-deep .el-form-item {
  display: flex;
  align-items: center;
  margin-bottom: 18px;
}

.qxInfoBox ::v-deep .el-form-item__content {
  flex: 1;
  display: flex;
  justify-content: flex-start;
}

.btnBox {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
  position: sticky;
  bottom: 0;
  padding: 10px 0;
  z-index: 1;
}

.FormBox {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin-top: 10px;
  overflow-y: auto;
  overflow-x: hidden;
  padding-bottom: 20px;
}

.FormBox .el-form {
  flex: 1;
}

.upload-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  max-width: 100%;
}

.upload-container ::v-deep .el-upload--picture-card {
  width: 100px;
  height: 100px;
  line-height: 100px;
  background: rgba(26, 58, 111, 0.3);
  border: 1px dashed rgba(255, 255, 255, 0.3);
  transition: all 0.3s ease;
}

.upload-container ::v-deep .el-upload--picture-card:hover {
  background: rgba(26, 58, 111, 0.5);
  border-color: #005BAA;
}

.upload-container ::v-deep .el-upload-list--picture-card .el-upload-list__item {
  width: 100px;
  height: 100px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(26, 58, 111, 0.3);
}

.upload-container ::v-deep .el-upload-list--picture-card {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 0;
}

.upload-container ::v-deep .el-upload-list--picture-card .el-upload-list__item-actions {
  background: rgba(0, 0, 0, 0.5);
}

.upload-container ::v-deep .el-upload-list--picture-card .el-upload-list__item-actions span {
  color: #fff;
}

.upload-container ::v-deep .el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete {
  color: #fff;
}

.upload-container ::v-deep .el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-preview {
  color: #fff;
}

.upload-container ::v-deep .el-dialog {
  background: rgba(19, 32, 57, 0.95);
  border-radius: 10px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.upload-container ::v-deep .el-dialog__title {
  color: #fff;
}

.upload-container ::v-deep .el-dialog__body img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

/* 自定义滚动条样式 */
.FormBox::-webkit-scrollbar {
  width: 6px;
}

.FormBox::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
}

.FormBox::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
}
.qxInfoBox ::v-deep .el-form-item__label:before {
  display: none;
}


.qxInfoBox :deep(.el-select__placeholder),
.qxInfoBox :deep(.el-select__input),
.qxInfoBox :deep(.el-select__caret) {
  color: #fff !important;
}

/* 按钮样式 */
.qxInfoBox ::v-deep .el-button {
  /* background-color: #1A3A6F; */
  /* border: 1px solid #005BAA; */
  color: #fff;
  border-radius: 4px;
  transition: all 0.3s ease;
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.qxInfoBox ::v-deep .el-button:hover {
  /* background-color: #005BAA; */
  /* border-color: #1A3A6F; */
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.qxInfoBox ::v-deep .el-button:active {
  transform: translateY(1px);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.qxInfoBox ::v-deep .el-button--danger {
  background-color: #D32F2F;
  border-color: #B71C1C;
}

.qxInfoBox ::v-deep .el-button--danger:hover {
  background-color: #F44336;
  border-color: #D32F2F;
}

.qxInfoBox ::v-deep .el-button--success {
  background-color: #4CAF50;
  border-color: #388E3C;
}

.qxInfoBox ::v-deep .el-button--success:hover {
  background-color: #66BB6A;
  border-color: #4CAF50;
}

/* 确保下拉框与主题保持一致 */
.qxInfoBox ::v-deep .el-select-dropdown {
  background: var(--card-background) !important;
  border: 1px solid var(--border-color) !important;
  border-radius: var(--small-radius) !important;
  box-shadow: var(--card-shadow) !important;
}

.qxInfoBox ::v-deep .el-select-dropdown__item {
  color: #fff !important;
}

.qxInfoBox ::v-deep .el-select-dropdown__item.hover, 
.qxInfoBox ::v-deep .el-select-dropdown__item:hover {
  background: var(--hover-background) !important;
}

.qxInfoBox ::v-deep .el-select-dropdown__item.selected {
  color: var(--highlight-color) !important;
  font-weight: bold;
  background: var(--secondary-color) !important;
}

.qxInfoBox ::v-deep .el-popper__arrow::before {
  background: var(--card-background) !important;
  border-color: var(--border-color) !important;
}

.qxInfoBox ::v-deep .el-form-item__label:before {
  display: none;
}
</style>
